/*Shift-JIS*/
/*UTF-8*/
/********************************************************************************/
/*ソース名:                                                                       */
/*　　pf_mem.h                                                                    */
/*機能:                                                                         */
/*　　 メモリを管理する                    　　　　　　　　　　　　　　　　                                                                                     */
/*作成者:                                                                       */
/*　　2010/02 関（CBSﾃｸﾉ）                                                                                                                                       */
/********************************************************************************/
/*変更履歴:                                                                     */
/*　2010/02　関　　新規作成                                                                                                                                    */
/********************************************************************************/
#ifndef __PF_MEM_MAN_H_
#define __PF_MEM_MAN_H_

/**************************************
 * マクロ
 */
#ifndef assert
#define assert( a ) ((a) ? (VOID)0 : printf("%s:%d:%s\n", __FILE__, __LINE__, #a ))
#endif

/* file access mode */
#ifndef OS_FULLPATH
#define OS_FULLPATH 1024
#endif
#define BIN_FILE_READ	"rb"
#define BIN_FILE_WRITE	"wb"
/* memory relation */
#define HEAP_SIZE			(1U<<12)   /* 4kb OSのメモリページのサイズ */
#define BLOCK_SIZE			(1U<<20)	/* 1MB 本機能において、ブロック(最大連続領域)のサイズ */

#ifndef MIN_PAGE_SIZE_BIT
#define MIN_PAGE_SIZE_BIT	14  /* 16 kb */
#endif
#define MIN_PAGE_SIZE		(1UL<<MIN_PAGE_SIZE_BIT)   /* 1kb 本機能において、最小単位メモリ領域のサイズ */
#if ( BLOCK_SIZE <= (1<<30) ) 		/* 最大１GB */
#if ( MIN_PAGE_SIZE >= 512 ) 		/* 最小512 byte */
#if BLOCK_SIZE == MIN_PAGE_SIZE
#define FLG_BIT_NUM  0
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<1)
#define FLG_BIT_NUM  1
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<2)
#define FLG_BIT_NUM  2
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<3)
#define FLG_BIT_NUM  3
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<4)
#define FLG_BIT_NUM  4
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<5)
#define FLG_BIT_NUM  5
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<6)
#define FLG_BIT_NUM  6
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<7)
#define FLG_BIT_NUM  7
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<8)
#define FLG_BIT_NUM  8
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<9)
#define FLG_BIT_NUM  9
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<10)
#define FLG_BIT_NUM  10
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<11)
#define FLG_BIT_NUM  11
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<12)
#define FLG_BIT_NUM  12
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<13)
#define FLG_BIT_NUM  13
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<14)
#define FLG_BIT_NUM  14
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<15)
#define FLG_BIT_NUM  15
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<16)
#define FLG_BIT_NUM  16
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<17)
#define FLG_BIT_NUM  17
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<18)
#define FLG_BIT_NUM  18
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<19)
#define FLG_BIT_NUM  19
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<20)
#define FLG_BIT_NUM  20
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<21)
#define FLG_BIT_NUM  21
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<22)
#define FLG_BIT_NUM  22
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<23)
#define FLG_BIT_NUM  23
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<24)
#define FLG_BIT_NUM  24
#elif BLOCK_SIZE == (MIN_PAGE_SIZE<<25)
#define FLG_BIT_NUM  25
#endif
#ifdef FLG_BIT_NUM
#define GET_DEF_LIMIT( Mega )	( ( (Mega)*(1<<20) ) / BLOCK_SIZE )
#define MIN_MEM_SIZE			100
#define ALIGNMENT_SIZE			16
#define HEADER_SIZE		((( sizeof( page_header ) - 1 )/(ALIGNMENT_SIZE))*ALIGNMENT_SIZE+ALIGNMENT_SIZE)
#define getheader(a)		((page_header*)(a))




typedef struct __PAGE_HEADER__
{
	const CHAR  *_BLOCK_HEAD_;
	VOID * p_block;			/* addr. of father */			/* 4~8 byte*/
	VOID * pre_block;			/* the addr. of pre block */   /* 4~8 byte*/
	VOID * next_block;			/* the addr. of next block */   /* 4~8 byte*/
	VOID * pre_page;			/* the addr. of pre block */   /* 4~8 byte*/
	VOID * next_page;			/* the addr. of next block */   /* 4~8 byte*/
	U4 ul_firstflg;	/* flags of the first half */	/* 4 byte*/
	U4 ul_secondflg; /* flags of the second half */  /* 4 byte*/
	UCHAR page_size;    /* page size. left shift bits of MIN_PAGE_SIZE */  /* 1 byte*/
	UCHAR block_flag;
	buffer_owner_info  buf_owner;		/* owner's id */                /* 6 byte*/
}page_header;
typedef struct __PAGE_SIZE_INFO__
{
	VOID * page_free;		/* blocks that is in use.*/
	U4 page_size;    /* byte */
	U4 bit_mask;		/* mask of the using flag bit */
}page_size_info;

typedef struct _MEMBLOCK_MANAGER{	/* manage the blocks */
	VOID * blk_old;			/* When memory is not enough, these blocks are swapped out*/
	VOID * blk_idle;			/* free blocks */
	VOID * blk_in_use;			/* blocks that are in use.*/
	S2     blk_old_cnter;
	S2     blk_idle_cnter;
	S2     blk_in_use_cnter;
}block_manager;
#else
#error "There is something wrong with the value of BLOCK_SIZE and MIN_PAGE_SIZE."
#endif
#else
#error "The size of minimum pages is smaller than 0.5KB."
#endif
#else
#error "The size of blocks is larger than 1GB."
#endif
#endif /* MEMINTERNAL_H_ */
